package org.skatiger.jrove.spring.tags.renderer;

import java.io.IOException;
import java.util.List;

import org.skatiger.jrove.ResponseWriter;
import org.skatiger.jrove.ViewContext;
import org.skatiger.jrove.component.JroveAttr;
import org.skatiger.jrove.component.NamingContainer;
import org.skatiger.jrove.component.UIComponent;
import org.skatiger.jrove.renderer.Html;
import org.skatiger.jrove.renderer.HtmlRendererBase;
import org.skatiger.jrove.renderer.RendererUtils;
import org.skatiger.jrove.spring.tags.component.OutputBindErrors;
import org.springframework.validation.Errors;
import org.springframework.validation.ObjectError;
import org.springframework.web.servlet.support.RequestContext;

public class OutputBindErrorsRenderer extends HtmlRendererBase {
    @Override
    public void encodeBegin(ViewContext context, UIComponent component)
            throws IOException {
        super.encodeBegin(context, component);
        OutputBindErrors bindErrors = (OutputBindErrors) component;
        Errors errors = bindErrors.getErrors();
        String var = bindErrors.getVar();
        bindErrors.capturePreivousValue(context);
        context.setAttribute(var, errors);
        ResponseWriter writer = context.getResponseWriter();
        writer.startElement(Html.BLOCKQUOTE_ELEM, component);
        renderId(context, component);
        RendererUtils.renderHtmlStandardAttributes(writer, component);
        renderHeader(context, component);
    }

    private String calendarId(ViewContext context, UIComponent component,
            String element) {
        return component.getId() + NamingContainer.SEPARATOR_CHAR + element;
    }

    @Override
    public boolean isRendersChildren() {
        return true;
    }

    @Override
    public void encodeChildren(ViewContext context, UIComponent component)
            throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        OutputBindErrors bindErrors = (OutputBindErrors) component;
        RequestContext requestContext = bindErrors.getRequestContext();
        Errors errors = bindErrors.getErrors();
        String ul_id = calendarId(context, component, Html.UL_ELEM);

        writer.startElement(Html.UL_ELEM, component);
        writer.writeAttribute(Html.ID_ATTR, ul_id, null);
        writer.writeAttribute(Html.STYLE_ATTR, "display:none", null);
        List<ObjectError> objerrs = (errors.getAllErrors());
        for (ObjectError objectError : objerrs) {
            writer.startElement(Html.LI_ELEM, component);
            writer.writeText(requestContext.getMessage(objectError), null);
            writer.endElement(Html.LI_ELEM);
        }
        writer.endElement(Html.UL_ELEM);
    }

    public void renderHeader(ViewContext context, UIComponent component)
            throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        OutputBindErrors bindErrors = (OutputBindErrors) component;
        RequestContext requestContext = bindErrors.getRequestContext();

        writer.startElement(Html.H3_ELEM, component);
        String title = requestContext.getMessage(
                "outputBindErrors.header.title", "Click me show details!");
        writer.writeAttribute(Html.TITLE_ATTR, title, null);
        String ul_id = calendarId(context, component, Html.UL_ELEM);
        writer.writeAttribute("onclick", "$('#" + ul_id + "').toggle()", null);

        UIComponent header = (UIComponent) component.getAttributes().get(
                JroveAttr.HEADER_FACET_NAME);
        if (header != null) {
            writer.writeAttribute(Html.CLASS_ATTR, JroveAttr.HEADER_CLASS_NAME,
                    null);
            header.encodeAll(context);
        } else {
            Errors errors = bindErrors.getErrors();
            String headerContent = requestContext.getMessage(
                    "outputBindErrors.header.label",
                    new Object[] { errors.getErrorCount() }, "found errors");
            writer.writeText(headerContent, null);
        }
        writer.endElement(Html.H3_ELEM);
    }

    public void renderFooter(ViewContext context, UIComponent component)
            throws IOException {
        UIComponent footer = (UIComponent) component.getAttributes().get(
                JroveAttr.FOOTER_FACET_NAME);
        if (footer != null) {
            ResponseWriter writer = context.getResponseWriter();
            writer.startElement(Html.H3_ELEM, footer);
            writer.writeAttribute(Html.CLASS_ATTR, JroveAttr.FOOTER_CLASS_NAME,
                    null);
            footer.encodeAll(context);
            writer.endElement(Html.H3_ELEM);
        }
    }

    @Override
    public void encodeEnd(ViewContext context, UIComponent component)
            throws IOException {
        super.encodeEnd(context, component);
        ResponseWriter writer = context.getResponseWriter();
        renderFooter(context, component);
        writer.endElement(Html.BLOCKQUOTE_ELEM);
        OutputBindErrors bindErrors = (OutputBindErrors) component;
        bindErrors.restorePreivousValue(context);
    }
}
